package com.example.dict1.service;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.dict1.dto.DictDTO;
import com.example.dict1.mapper.DictMapper;
import com.example.dict1.vo.DictVO;
import com.example.dict1.entity.Dict;
import lombok.experimental.Accessors;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;


@Service
@Accessors(chain = true)
public class DictService {

    @Resource
    private DictMapper dictMapper;


    /**
     * 添加操作
     * @param vO
     * @return id
     */
    public Long save(DictVO vO) {
        Dict bean = new Dict();
        BeanUtils.copyProperties(vO, bean);
        dictMapper.insert(bean);
        return bean.getId();
    }

    /**
     * 删除对应id的字典
     * @param id
     */
    public void delete(Long id) {
        int affectRows = dictMapper.deleteById(id);
        if (affectRows == 0) {
            throw new OptimisticLockingFailureException("Can't delete entity:" + id);
        }
    }

    /**
     * @param id 要被更新实体的id
     * @param vO 更新的数值
     */
    public void update(Long id, DictVO vO) {
        Dict bean = new Dict();
        BeanUtils.copyProperties(vO, bean);
        bean.setId(id);
        dictMapper.updateById(bean);
    }

    public DictDTO getById(Long id) {
        Dict original = requireOne(id);
        return toDTO(original);
    }

    /**
     * 按照id查询
     * @param dict
     * @return 按照id查询出来的字典
     */
    public Dict query(Dict dict) {
        Wrapper<Dict> wrapper = new QueryWrapper<>(dict);
        return dictMapper.selectOne(wrapper);
    }

    /**
     * 查询所有字典集
     * @return List dict
     */
    public List<Dict> list() {
        List<Dict> dictList = dictMapper.selectList(null);
        if (dictList.isEmpty()) {
            throw new OptimisticLockingFailureException("Can't fill entity:");
        }
        return dictList;
    }

    /**
     * 根据参数查询
     * @param dict 实体类参数
     * @return List<dict> 结果集
     */
    public List<Dict> list(Dict dict) {
        return dictMapper.selectList(wrapper(dict));
    }


    /**
     * 根据参数进行分页查询
     * @param dict 字典实体类
     * @param current 当前页数
     * @param size 分页大小
     * @return 分页对象
     */
    public IPage<Dict> list(Dict dict,Long current, Long size) {
        IPage<Dict> page = new Page<>(current, size);
        IPage<Dict> dictIPage = dictMapper.selectPage(page, wrapper(dict));
        if (!ObjectUtil.isNotNull(dictIPage)) throw new RuntimeException("数据库没有结果");
        return dictIPage;
    }

    /**
     * @param type    根据type类型查询(分页查询)
     * @param current 当前页数
     * @param size    每页大小
     * @return IPage<Dict> 分页对象
     */

    public IPage<Dict> queryByType(String type, Long current, Long size) {

        LambdaQueryWrapper<Dict> queryWrapper = new LambdaQueryWrapper<>();
        //条件包装类
        IPage<Dict> page = new Page<>(current, size);
        //分页对象
        queryWrapper
                .eq(Dict::getType, type)
                //找到对应的type
                .orderByAsc(Dict::getId);
                //升序查询;

        IPage<Dict> dictIPage = dictMapper.selectPage(page, queryWrapper);
        //分页查询

        if (!ObjectUtil.isNotNull(dictIPage)) throw new RuntimeException("数据库没有结果");
        //判断数据库是否有结果
        return dictIPage;
    }

    /**
     * 模糊查询
     *
     * @param col 行
     * @param val 模糊查询的值
     * @return 模糊查询结果集
     */
    public List<Dict> like(String col, String val) {
        return dictMapper.selectList
                (new QueryWrapper<Dict>().
                        like(col, val).
                        orderByDesc("id"));
    }

    /**
     * 根据id批量删除
     * @param ids 需要删除的id
     * @return 布尔值
     */
    public boolean deleteBatch(ArrayList<Long> ids) {
        if (dictMapper.deleteBatchIds(ids) == 0) {
            throw new OptimisticLockingFailureException("Can't delete entity:");
        }
        return true;
    }

    /**
     * 批量增加
     * @param dictList 需要插入的实体集合
     * @return 布尔值
     */
    public void saveBatch(ArrayList<Dict> dictList) {
        //使用foreach把前端传来所有数据依次插入到数据库
        dictList.stream().forEach(dict -> dictMapper.insert(dict));
    }

    /**
     * 使用外键连表查询
     * @param foreignKey 外键id
     * @return dict object
     */
    public List<Dict> queryByForeignKey(Integer foreignKey) {
        if (ObjectUtil.isNull(dictMapper.queryByForeignKey(foreignKey))) {
            throw new NoSuchElementException("Resource not found: " + foreignKey);
        }
        return dictMapper.queryByForeignKey(foreignKey);
    }

    private DictDTO toDTO(Dict original) {
        DictDTO bean = new DictDTO();
        BeanUtils.copyProperties(original, bean);
        return bean;
    }

    /**
     * @param id dict实体类主键
     * @return 查询到的实体类
     */
    private Dict requireOne(Long id) {
        return Optional
                .ofNullable(dictMapper.selectById(id))
                .orElseThrow(() -> new NoSuchElementException("Resource not found: " + id));
    }


    /**
     * 私有包装类用于条件查询
     * @param dict 实体类
     * @return 条件包装类
     */
    private QueryWrapper<Dict> wrapper(Dict dict){
        QueryWrapper<Dict> dictQueryWrapper = new QueryWrapper<>();

        if (StringUtils.isNotBlank(dict.getRemarks())){
            dictQueryWrapper.like("remarks",dict.getRemarks());
        }
        if (StringUtils.isNotBlank(dict.getLabel())){
            dictQueryWrapper.eq("label",dict.getLabel());
        }
        if (StringUtils.isNotBlank(dict.getType())){
            dictQueryWrapper.eq("type",dict.getType());
        }
        if (StringUtils.isNotBlank(dict.getValue())){
            dictQueryWrapper.eq("value",dict.getRemarks());
        }
        return dictQueryWrapper;
    }


}
